package com.whosly.fast.web.quickly.util;

import org.apache.commons.lang3.ArrayUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.NumberFormat;
import java.util.Set;

/**
 * 字符串格式化
 */
public final class StrFormatter {
    public static final String EMPTY_JSON = "{}";
    public static final char C_BACKSLASH = '\\';
    public static final char C_DELIM_START = '{';
    public static final char C_DELIM_END = '}';

    /**
     * 格式化字符串<br>
     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
     * 如果想输出 {} 使用 \\转义 { 即可，如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
     * 例：<br>
     * 通常使用：format("this is {} for {}", "a", "b") -> this is a for b<br>
     * 转义{}： format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
     * 转义\： format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
     *
     * @param strPattern 字符串模板
     * @param argArray 参数列表
     * @return 结果
     */
    public static String format(final String strPattern, final Object... argArray)
    {
        if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
        {
            return strPattern;
        }
        final int strPatternLength = strPattern.length();

        // 初始化定义好的长度以获得更好的性能
        StringBuilder sbuf = new StringBuilder(strPatternLength + 50);

        int handledPosition = 0;
        int delimIndex;// 占位符所在位置
        for (int argIndex = 0; argIndex < argArray.length; argIndex++)
        {
            delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
            if (delimIndex == -1)
            {
                if (handledPosition == 0)
                {
                    return strPattern;
                }
                else
                { // 字符串模板剩余部分不再包含占位符，加入剩余部分后返回结果
                    sbuf.append(strPattern, handledPosition, strPatternLength);
                    return sbuf.toString();
                }
            }
            else
            {
                if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
                {
                    if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
                    {
                        // 转义符之前还有一个转义符，占位符依旧有效
                        sbuf.append(strPattern, handledPosition, delimIndex - 1);
                        sbuf.append(Convert.utf8Str(argArray[argIndex]));
                        handledPosition = delimIndex + 2;
                    }
                    else
                    {
                        // 占位符被转义
                        argIndex--;
                        sbuf.append(strPattern, handledPosition, delimIndex - 1);
                        sbuf.append(C_DELIM_START);
                        handledPosition = delimIndex + 1;
                    }
                }
                else
                {
                    // 正常占位符
                    sbuf.append(strPattern, handledPosition, delimIndex);
                    sbuf.append(Convert.utf8Str(argArray[argIndex]));
                    handledPosition = delimIndex + 2;
                }
            }
        }
        // 加入最后一个占位符后所有的字符
        sbuf.append(strPattern, handledPosition, strPattern.length());

        return sbuf.toString();
    }

    /**
     * 类型转换器
     */
    public final class Convert {
        /**
         * 转换为字符串<br>
         * 如果给定的值为null，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @param defaultValue 转换错误时的默认值
         * @return 结果
         */
        public static String toStr(Object value, String defaultValue)
        {
            if (null == value)
            {
                return defaultValue;
            }
            if (value instanceof String)
            {
                return (String) value;
            }
            return value.toString();
        }

        /**
         * 转换为字符串<br>
         * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<code>null</code><br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @return 结果
         */
        public static String toStr(Object value)
        {
            return toStr(value, null);
        }

        /**
         * 转换为字符<br>
         * 如果给定的值为null，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @param defaultValue 转换错误时的默认值
         * @return 结果
         */
        public static Character toChar(Object value, Character defaultValue)
        {
            if (null == value)
            {
                return defaultValue;
            }
            if (value instanceof Character)
            {
                return (Character) value;
            }

            final String valueStr = toStr(value, null);
            return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0);
        }

        /**
         * 转换为字符<br>
         * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<code>null</code><br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @return 结果
         */
        public static Character toChar(Object value)
        {
            return toChar(value, null);
        }

        /**
         * 转换为byte<br>
         * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @param defaultValue 转换错误时的默认值
         * @return 结果
         */
        public static Byte toByte(Object value, Byte defaultValue)
        {
            if (value == null)
            {
                return defaultValue;
            }
            if (value instanceof Byte)
            {
                return (Byte) value;
            }
            if (value instanceof Number)
            {
                return ((Number) value).byteValue();
            }
            final String valueStr = toStr(value, null);
            if (StringUtils.isEmpty(valueStr))
            {
                return defaultValue;
            }
            try
            {
                return Byte.parseByte(valueStr);
            }
            catch (Exception e)
            {
                return defaultValue;
            }
        }

        /**
         * 转换为byte<br>
         * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<code>null</code><br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @return 结果
         */
        public static Byte toByte(Object value)
        {
            return toByte(value, null);
        }

        /**
         * 转换为Short<br>
         * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @param defaultValue 转换错误时的默认值
         * @return 结果
         */
        public static Short toShort(Object value, Short defaultValue)
        {
            if (value == null)
            {
                return defaultValue;
            }
            if (value instanceof Short)
            {
                return (Short) value;
            }
            if (value instanceof Number)
            {
                return ((Number) value).shortValue();
            }
            final String valueStr = toStr(value, null);
            if (StringUtils.isEmpty(valueStr))
            {
                return defaultValue;
            }
            try
            {
                return Short.parseShort(valueStr.trim());
            }
            catch (Exception e)
            {
                return defaultValue;
            }
        }

        /**
         * 转换为Short<br>
         * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<code>null</code><br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @return 结果
         */
        public static Short toShort(Object value)
        {
            return toShort(value, null);
        }

        /**
         * 转换为Number<br>
         * 如果给定的值为空，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @param defaultValue 转换错误时的默认值
         * @return 结果
         */
        public static Number toNumber(Object value, Number defaultValue)
        {
            if (value == null)
            {
                return defaultValue;
            }
            if (value instanceof Number)
            {
                return (Number) value;
            }
            final String valueStr = toStr(value, null);
            if (StringUtils.isEmpty(valueStr))
            {
                return defaultValue;
            }
            try
            {
                return NumberFormat.getInstance().parse(valueStr);
            }
            catch (Exception e)
            {
                return defaultValue;
            }
        }

        /**
         * 转换为Number<br>
         * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @return 结果
         */
        public static Number toNumber(Object value)
        {
            return toNumber(value, null);
        }

        /**
         * 转换为int<br>
         * 如果给定的值为空，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @param defaultValue 转换错误时的默认值
         * @return 结果
         */
        public static Integer toInt(Object value, Integer defaultValue)
        {
            if (value == null)
            {
                return defaultValue;
            }
            if (value instanceof Integer)
            {
                return (Integer) value;
            }
            if (value instanceof Number)
            {
                return ((Number) value).intValue();
            }
            final String valueStr = toStr(value, null);
            if (StringUtils.isEmpty(valueStr))
            {
                return defaultValue;
            }
            try
            {
                return Integer.parseInt(valueStr.trim());
            }
            catch (Exception e)
            {
                return defaultValue;
            }
        }

        /**
         * 转换为int<br>
         * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<code>null</code><br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @return 结果
         */
        public static Integer toInt(Object value)
        {
            return toInt(value, null);
        }

        /**
         * 转换为Integer数组<br>
         *
         * @param str 被转换的值
         * @return 结果
         */
        public static Integer[] toIntArray(String str)
        {
            return toIntArray(",", str);
        }

        /**
         * 转换为Long数组<br>
         *
         * @param str 被转换的值
         * @return 结果
         */
        public static Long[] toLongArray(String str)
        {
            return toLongArray(",", str);
        }

        /**
         * 转换为Integer数组<br>
         *
         * @param split 分隔符
         * @param split 被转换的值
         * @return 结果
         */
        public static Integer[] toIntArray(String split, String str)
        {
            if (StringUtils.isEmpty(str))
            {
                return new Integer[] {};
            }
            String[] arr = str.split(split);
            final Integer[] ints = new Integer[arr.length];
            for (int i = 0; i < arr.length; i++)
            {
                final Integer v = toInt(arr[i], 0);
                ints[i] = v;
            }
            return ints;
        }

        /**
         * 转换为Long数组<br>
         *
         * @param split 分隔符
         * @param str 被转换的值
         * @return 结果
         */
        public static Long[] toLongArray(String split, String str)
        {
            if (StringUtils.isEmpty(str))
            {
                return new Long[] {};
            }
            String[] arr = str.split(split);
            final Long[] longs = new Long[arr.length];
            for (int i = 0; i < arr.length; i++)
            {
                final Long v = toLong(arr[i], null);
                longs[i] = v;
            }
            return longs;
        }

        /**
         * 转换为String数组<br>
         *
         * @param str 被转换的值
         * @return 结果
         */
        public static String[] toStrArray(String str)
        {
            if (StringUtils.isEmpty(str))
            {
                return new String[] {};
            }
            return toStrArray(",", str);
        }

        /**
         * 转换为String数组<br>
         *
         * @param split 分隔符
         * @param split 被转换的值
         * @return 结果
         */
        public static String[] toStrArray(String split, String str)
        {
            return str.split(split);
        }

        /**
         * 转换为long<br>
         * 如果给定的值为空，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @param defaultValue 转换错误时的默认值
         * @return 结果
         */
        public static Long toLong(Object value, Long defaultValue)
        {
            if (value == null)
            {
                return defaultValue;
            }
            if (value instanceof Long)
            {
                return (Long) value;
            }
            if (value instanceof Number)
            {
                return ((Number) value).longValue();
            }
            final String valueStr = toStr(value, null);
            if (StringUtils.isEmpty(valueStr))
            {
                return defaultValue;
            }
            try
            {
                // 支持科学计数法
                return new BigDecimal(valueStr.trim()).longValue();
            }
            catch (Exception e)
            {
                return defaultValue;
            }
        }

        /**
         * 转换为long<br>
         * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<code>null</code><br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @return 结果
         */
        public static Long toLong(Object value)
        {
            return toLong(value, null);
        }

        /**
         * 转换为double<br>
         * 如果给定的值为空，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @param defaultValue 转换错误时的默认值
         * @return 结果
         */
        public static Double toDouble(Object value, Double defaultValue)
        {
            if (value == null)
            {
                return defaultValue;
            }
            if (value instanceof Double)
            {
                return (Double) value;
            }
            if (value instanceof Number)
            {
                return ((Number) value).doubleValue();
            }
            final String valueStr = toStr(value, null);
            if (StringUtils.isEmpty(valueStr))
            {
                return defaultValue;
            }
            try
            {
                // 支持科学计数法
                return new BigDecimal(valueStr.trim()).doubleValue();
            }
            catch (Exception e)
            {
                return defaultValue;
            }
        }

        /**
         * 转换为double<br>
         * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @return 结果
         */
        public static Double toDouble(Object value)
        {
            return toDouble(value, null);
        }

        /**
         * 转换为Float<br>
         * 如果给定的值为空，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @param defaultValue 转换错误时的默认值
         * @return 结果
         */
        public static Float toFloat(Object value, Float defaultValue)
        {
            if (value == null)
            {
                return defaultValue;
            }
            if (value instanceof Float)
            {
                return (Float) value;
            }
            if (value instanceof Number)
            {
                return ((Number) value).floatValue();
            }
            final String valueStr = toStr(value, null);
            if (StringUtils.isEmpty(valueStr))
            {
                return defaultValue;
            }
            try
            {
                return Float.parseFloat(valueStr.trim());
            }
            catch (Exception e)
            {
                return defaultValue;
            }
        }

        /**
         * 转换为Float<br>
         * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @return 结果
         */
        public static Float toFloat(Object value)
        {
            return toFloat(value, null);
        }

        /**
         * 转换为boolean<br>
         * String支持的值为：true、false、yes、ok、no，1,0 如果给定的值为空，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @param defaultValue 转换错误时的默认值
         * @return 结果
         */
        public static Boolean toBool(Object value, Boolean defaultValue)
        {
            if (value == null)
            {
                return defaultValue;
            }
            if (value instanceof Boolean)
            {
                return (Boolean) value;
            }
            String valueStr = toStr(value, null);
            if (StringUtils.isEmpty(valueStr))
            {
                return defaultValue;
            }
            valueStr = valueStr.trim().toLowerCase();
            switch (valueStr)
            {
                case "true":
                case "yes":
                case "ok":
                case "1":
                    return true;
                case "false":
                case "no":
                case "0":
                    return false;
                default:
                    return defaultValue;
            }
        }

        /**
         * 转换为boolean<br>
         * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @return 结果
         */
        public static Boolean toBool(Object value)
        {
            return toBool(value, null);
        }

        /**
         * 转换为Enum对象<br>
         * 如果给定的值为空，或者转换失败，返回默认值<br>
         *
         * @param clazz Enum的Class
         * @param value 值
         * @param defaultValue 默认值
         * @return Enum
         */
        public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value, E defaultValue)
        {
            if (value == null)
            {
                return defaultValue;
            }
            if (clazz.isAssignableFrom(value.getClass()))
            {
                @SuppressWarnings("unchecked")
                E myE = (E) value;
                return myE;
            }
            final String valueStr = toStr(value, null);
            if (StringUtils.isEmpty(valueStr))
            {
                return defaultValue;
            }
            try
            {
                return Enum.valueOf(clazz, valueStr);
            }
            catch (Exception e)
            {
                return defaultValue;
            }
        }

        /**
         * 转换为Enum对象<br>
         * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
         *
         * @param clazz Enum的Class
         * @param value 值
         * @return Enum
         */
        public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value)
        {
            return toEnum(clazz, value, null);
        }

        /**
         * 转换为BigInteger<br>
         * 如果给定的值为空，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @param defaultValue 转换错误时的默认值
         * @return 结果
         */
        public static BigInteger toBigInteger(Object value, BigInteger defaultValue)
        {
            if (value == null)
            {
                return defaultValue;
            }
            if (value instanceof BigInteger)
            {
                return (BigInteger) value;
            }
            if (value instanceof Long)
            {
                return BigInteger.valueOf((Long) value);
            }
            final String valueStr = toStr(value, null);
            if (StringUtils.isEmpty(valueStr))
            {
                return defaultValue;
            }
            try
            {
                return new BigInteger(valueStr);
            }
            catch (Exception e)
            {
                return defaultValue;
            }
        }

        /**
         * 转换为BigInteger<br>
         * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @return 结果
         */
        public static BigInteger toBigInteger(Object value)
        {
            return toBigInteger(value, null);
        }

        /**
         * 转换为BigDecimal<br>
         * 如果给定的值为空，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @param defaultValue 转换错误时的默认值
         * @return 结果
         */
        public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue)
        {
            if (value == null)
            {
                return defaultValue;
            }
            if (value instanceof BigDecimal)
            {
                return (BigDecimal) value;
            }
            if (value instanceof Long)
            {
                return new BigDecimal((Long) value);
            }
            if (value instanceof Double)
            {
                return BigDecimal.valueOf((Double) value);
            }
            if (value instanceof Integer)
            {
                return new BigDecimal((Integer) value);
            }
            final String valueStr = toStr(value, null);
            if (StringUtils.isEmpty(valueStr))
            {
                return defaultValue;
            }
            try
            {
                return new BigDecimal(valueStr);
            }
            catch (Exception e)
            {
                return defaultValue;
            }
        }

        /**
         * 转换为BigDecimal<br>
         * 如果给定的值为空，或者转换失败，返回默认值<br>
         * 转换失败不会报错
         *
         * @param value 被转换的值
         * @return 结果
         */
        public static BigDecimal toBigDecimal(Object value)
        {
            return toBigDecimal(value, null);
        }

        /**
         * 将对象转为字符串<br>
         * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
         *
         * @param obj 对象
         * @return 字符串
         */
        public static String utf8Str(Object obj)
        {
            return str(obj, CharsetKit.CHARSET_UTF_8);
        }

        /**
         * 将对象转为字符串<br>
         * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
         *
         * @param obj 对象
         * @param charsetName 字符集
         * @return 字符串
         */
        public static String str(Object obj, String charsetName)
        {
            return str(obj, Charset.forName(charsetName));
        }

        /**
         * 将对象转为字符串<br>
         * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
         *
         * @param obj 对象
         * @param charset 字符集
         * @return 字符串
         */
        public static String str(Object obj, Charset charset)
        {
            if (null == obj)
            {
                return null;
            }

            if (obj instanceof String)
            {
                return (String) obj;
            }
            else if (obj instanceof byte[])
            {
                return str((byte[]) obj, charset);
            }
            else if (obj instanceof Byte[])
            {
                byte[] bytes = ArrayUtils.toPrimitive((Byte[]) obj);
                return str(bytes, charset);
            }
            else if (obj instanceof ByteBuffer)
            {
                return str((ByteBuffer) obj, charset);
            }
            return obj.toString();
        }

        /**
         * 将byte数组转为字符串
         *
         * @param bytes byte数组
         * @param charset 字符集
         * @return 字符串
         */
        public static String str(byte[] bytes, String charset)
        {
            return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset));
        }

        /**
         * 解码字节码
         *
         * @param data 字符串
         * @param charset 字符集，如果此字段为空，则解码的结果取决于平台
         * @return 解码后的字符串
         */
        public static String str(byte[] data, Charset charset)
        {
            if (data == null)
            {
                return null;
            }

            if (null == charset)
            {
                return new String(data);
            }
            return new String(data, charset);
        }

        /**
         * 将编码的byteBuffer数据转换为字符串
         *
         * @param data 数据
         * @param charset 字符集，如果为空使用当前系统字符集
         * @return 字符串
         */
        public static String str(ByteBuffer data, String charset)
        {
            if (data == null)
            {
                return null;
            }

            return str(data, Charset.forName(charset));
        }

        /**
         * 将编码的byteBuffer数据转换为字符串
         *
         * @param data 数据
         * @param charset 字符集，如果为空使用当前系统字符集
         * @return 字符串
         */
        public static String str(ByteBuffer data, Charset charset)
        {
            if (null == charset)
            {
                charset = Charset.defaultCharset();
            }
            return charset.decode(data).toString();
        }

        // ----------------------------------------------------------------------- 全角半角转换
        /**
         * 半角转全角
         *
         * @param input String.
         * @return 全角字符串.
         */
        public static String toSBC(String input)
        {
            return toSBC(input, null);
        }

        /**
         * 半角转全角
         *
         * @param input String
         * @param notConvertSet 不替换的字符集合
         * @return 全角字符串.
         */
        public static String toSBC(String input, Set<Character> notConvertSet)
        {
            char[] c = input.toCharArray();
            for (int i = 0; i < c.length; i++)
            {
                if (null != notConvertSet && notConvertSet.contains(c[i]))
                {
                    // 跳过不替换的字符
                    continue;
                }

                if (c[i] == ' ')
                {
                    c[i] = '\u3000';
                }
                else if (c[i] < '\177')
                {
                    c[i] = (char) (c[i] + 65248);

                }
            }
            return new String(c);
        }

        /**
         * 全角转半角
         *
         * @param input String.
         * @return 半角字符串
         */
        public static String toDBC(String input)
        {
            return toDBC(input, null);
        }

        /**
         * 替换全角为半角
         *
         * @param text 文本
         * @param notConvertSet 不替换的字符集合
         * @return 替换后的字符
         */
        public static String toDBC(String text, Set<Character> notConvertSet)
        {
            char[] c = text.toCharArray();
            for (int i = 0; i < c.length; i++)
            {
                if (null != notConvertSet && notConvertSet.contains(c[i]))
                {
                    // 跳过不替换的字符
                    continue;
                }

                if (c[i] == '\u3000')
                {
                    c[i] = ' ';
                }
                else if (c[i] > '\uFF00' && c[i] < '\uFF5F')
                {
                    c[i] = (char) (c[i] - 65248);
                }
            }
            String returnString = new String(c);

            return returnString;
        }

        /**
         * 数字金额大写转换 先写个完整的然后将如零拾替换成零
         *
         * @param n 数字
         * @return 中文大写数字
         */
        public static String digitUppercase(double n)
        {
            String[] fraction = { "角", "分" };
            String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
            String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } };

            String head = n < 0 ? "负" : "";
            n = Math.abs(n);

            String s = "";
            for (int i = 0; i < fraction.length; i++)
            {
                // 优化double计算精度丢失问题
                BigDecimal nNum = new BigDecimal(n);
                BigDecimal decimal = new BigDecimal(10);
                BigDecimal scale = nNum.multiply(decimal).setScale(2, RoundingMode.HALF_EVEN);
                double d = scale.doubleValue();
                s += (digit[(int) (Math.floor(d * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
            }
            if (s.length() < 1)
            {
                s = "整";
            }
            int integerPart = (int) Math.floor(n);

            for (int i = 0; i < unit[0].length && integerPart > 0; i++)
            {
                String p = "";
                for (int j = 0; j < unit[1].length && n > 0; j++)
                {
                    p = digit[integerPart % 10] + unit[1][j] + p;
                    integerPart = integerPart / 10;
                }
                s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s;
            }
            return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整");
        }
    }

    /**
     * 字符集工具类
     */
    final class CharsetKit {
        /** ISO-8859-1 */
        public static final String ISO_8859_1 = "ISO-8859-1";
        /** UTF-8 */
        public static final String UTF_8 = "UTF-8";
        /** GBK */
        public static final String GBK = "GBK";

        /** ISO-8859-1 */
        public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
        /** UTF-8 */
        public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
        /** GBK */
        public static final Charset CHARSET_GBK = Charset.forName(GBK);

        /**
         * 转换为Charset对象
         *
         * @param charset 字符集，为空则返回默认字符集
         * @return Charset
         */
        public static Charset charset(String charset)
        {
            return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
        }

        /**
         * 转换字符串的字符集编码
         *
         * @param source 字符串
         * @param srcCharset 源字符集，默认ISO-8859-1
         * @param destCharset 目标字符集，默认UTF-8
         * @return 转换后的字符集
         */
        public static String convert(String source, String srcCharset, String destCharset)
        {
            return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
        }

        /**
         * 转换字符串的字符集编码
         *
         * @param source 字符串
         * @param srcCharset 源字符集，默认ISO-8859-1
         * @param destCharset 目标字符集，默认UTF-8
         * @return 转换后的字符集
         */
        public static String convert(String source, Charset srcCharset, Charset destCharset)
        {
            if (null == srcCharset)
            {
                srcCharset = StandardCharsets.ISO_8859_1;
            }

            if (null == destCharset)
            {
                destCharset = StandardCharsets.UTF_8;
            }

            if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
            {
                return source;
            }
            return new String(source.getBytes(srcCharset), destCharset);
        }

        /**
         * @return 系统字符集编码
         */
        public static String systemCharset()
        {
            return Charset.defaultCharset().name();
        }
    }

}
